package br.unb.graphics.inference;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyVetoException;
import java.text.DecimalFormat;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTabbedPane;

import br.unb.graphics.InterfaceFactory;
import br.unb.plugins.geral.view.XmlComboBox;
import br.unb.plugins.geral.view.XmlFactory;
import br.unb.statistic.distribution.GenericContinuousDistribution;
import br.unb.statistic.inference.Inference;
import br.unb.utils.Resource;
import br.unb.utils.Console;

public class InferenceFrame extends JInternalFrame {

    /**Keys used on .propertiesfile*/
    /**DistributionInferenceChart*/
    //JInternalFrame a;a.
    private static final String DISTRIBUTION_TITLE = "distributionTitle";
    private static final String DISTRIBUTION_X_AXIS = "distributionXAxis";
    private static final String DISTRIBUTION_Y_AXIS = "distributionYAxis";
    private static final String DISTRIBUTION_INTERPACKET_X_AXIS = "distributionInterPacketXAxis";
    private static final String DISTRIBUTION_PACKETS_PER_TIME_X_AXIS = "distributionPacketsPerTimeXAxis";
    /**PathInferenceChart*/
    private static final String PATH_TITLE = "pathTitle";
    private static final String PATH_X_AXIS = "pathXAxis";
    /**CDFInferenceChart */
    private static final String Y_AXIS = "yAxis";
    private static final String CDF_TITLE = "cdfTitle";
    private static final String CDF_X_AXIS = "cdfXAxis";
    /**TailInferenceChart */
    private static final String TAIL_TITLE = "tailTitle";
    private static final String TAIL_X_AXIS = "tailXAxis";
    /**VTPInferenceChart */
    private static final String VTP_TITLE = "vtpTitle";
    private static final String VTP_X_AXIS = "vtpXAxis";
    private static final String VTP_Y_AXIS = "vtpYAxis";
    /**LogVTPInferenceChart */
    private static final String LOG_VTP_TITLE = "logVtpTitle";
    private static final String LOG_VTP_X_AXIS = "logVtpXAxis";
    private static final String LOG_VTP_Y_AXIS = "logVtpYAxis";
    private static final String CHI_SQUARE_XML = "ChiSquare.xml";
    private static final String CDF_TAB_TITLE = "cdfTabTitle";
    private static final String TAIL_TAB_TITLE = "tailTabTitle";
    private static final String DISTRIBUTION_TAB_TITLE = "distributionTabTitle";
    private static final String PATH_TAB_TITLE = "pathTabTitle";
    //private static final String FILE_LABEL = "file";
    private static final String DEGREES_COMAND = "degreesCommand";
    private static final String DEGREES_ERROR = "degreesError";
    private static final String QUI = "qui";
    private static final String DEGREES = "degrees";
    private static final String WHITTLE = "whittleHurst";
    private static final String VTP = "vtpHurst";
    private static final String KETTANI = "kettaniHurst";
    private static final String PERIODOGRAM = "periodogramHurst";
    private static final String PACKETS_PER_TIME_TITLE = "packetsPerTimeTitle";
    private static final String INTER_PACKETS_TIMES_TITLE = "interPacketsTimesTitle";
    private static final String TIME_UNIT = "timeUnit";
    private static final String HURST_FRAME = "hurstFrameTitle";
    private static final String ALL_BUTTON = "allButton";
    private static final String WHITTLE_BUTTON = "whittleButton";
    private static final String VTP_BUTTON = "vtpButton";
    private static final String PERIODOGRAM_BUTTON = "periodogramButton";
    private static final String KETTANI_BUTTON = "kettaniButton";
    private static final String ESTIMATOR = "estimator";
    private static final String CALCULATE_HURST = "calculateHurst";
    private static final String QUI_FRAME = "quiFrameTitle";
    private static final String QUI_DISTRIBUTION = "quiDistribution";
    private static final String CALCULATE_QUI = "calculateQui";
    private static final String MEAN_LABEL = "meanLabel";
    private static final String VARIANCE_LABEL = "varianceLabel";
    private static final String CDF_ACTION = "cdf";
    private static final String TAIL_ACTION = "tail";
    private static final String DISTRIBUTION_ACTION = "distribution";
    private static final String VTP_ACTION = "vtp";
    private static final String REMOVE_TREND_ACTION = "remTrend";
    private static final String LOG_VTP_ACTION = "logVtp";
    private static final String SAMPLE_PATH_ACTION = "path";
    private static final String MEAN_ACTION = "mean";
    private static final String VARIANCE_ACTION = "variance";
    private static final String HURST_ACTION = "hurst";
    private static final String QUI_ACTION = "quiSquare";
    private static final String DEGREES_OF_FREEDOM_ACTION = "degreesOfFreedom";
    private static final String CALCULATE_HURST_ACTION = "calculateHurstAction";
    private static final String CALCULATE_QUI_ACTION = "calculateQuiAction";
    /** */
    private JComboBox quiCombo;
    private JPanel hPanel, qPanel, momentsPanel;
    private JRadioButton whittleButton, kettaniButton, varianceTimeButton, periodogramButton, allButton;
    private InferenceChart distChart, pathChart, vtpChart, logVtpChart, cdfChart, tailChart;
    private JMenuBar menubar;
    private JTabbedPane abas;
    private Inference inference;
    private InterfaceFactory ifactory;
    private JPanel parameterPanel;
    private String seriesName;
    private JFrame hurstFrame, quiFrame;
    private int currentQuiGridx = 0;
    GridBagConstraints c;
    private Action[] actions = {
        new DistributionAction(),
        new VarianceTimePlotAction(),
        new MeanAction(),
        new VarianceAction(),
        new HurstAction(),
        new QuiSquareAction(),
        new DegreesOfFreedomAction(),
        new CalculateHurstAction(),
        new CalculateQuiAction(),
        new PathAction(),
        new LogVarianceTimePlotAction(),
        new RemoveTrendAction(),
        new CDFAction(),
        new TailAction()
    };
    private boolean hasDistribution, hasVTP, hasPath, hasLogVTP, hasCdf, hasTail;

    public InferenceFrame(String s, Inference i) {
        super();
        hPanel = new JPanel(new GridBagLayout());
        qPanel = new JPanel();
        momentsPanel = new JPanel(new GridBagLayout());
        seriesName = s;
        inference = i;
        ifactory = new InterfaceFactory(Resource.InferenceFrame, actions);
        menubar = ifactory.createMenubar();
        String distTitle = ifactory.getResourceString(InferenceFrame.DISTRIBUTION_TITLE);
        String distYAxis = ifactory.getResourceString(InferenceFrame.DISTRIBUTION_Y_AXIS);
        String distXAxis;
        abas = new JTabbedPane();
        if (inference.getProcess().equals(Inference.PACKETS_PER_UNIT)) {
            this.setTitle(ifactory.getResourceString(InferenceFrame.PACKETS_PER_TIME_TITLE) + " " + seriesName);
            distXAxis = ifactory.getResourceString(InferenceFrame.DISTRIBUTION_PACKETS_PER_TIME_X_AXIS);
        } else if (inference.getProcess().equals(Inference.INTER_PACKET_TIMES)) {
            this.setTitle(ifactory.getResourceString(InferenceFrame.INTER_PACKETS_TIMES_TITLE) + " " + seriesName);
            distXAxis = ifactory.getResourceString(InferenceFrame.DISTRIBUTION_INTERPACKET_X_AXIS);
        } else {
            this.setTitle(seriesName);
            distXAxis = ifactory.getResourceString(InferenceFrame.DISTRIBUTION_X_AXIS);
        }
        logVtpChart = new InferenceChart(ifactory.getResourceString(LOG_VTP_TITLE), ifactory.getResourceString(LOG_VTP_X_AXIS), ifactory.getResourceString(LOG_VTP_Y_AXIS), InferenceChart.LINE_CHART);
        vtpChart = new InferenceChart(ifactory.getResourceString(VTP_TITLE), ifactory.getResourceString(VTP_X_AXIS), ifactory.getResourceString(VTP_Y_AXIS), InferenceChart.LINE_CHART);
        distChart = new InferenceChart(distTitle, distXAxis, distYAxis, InferenceChart.BAR_CHART);
        pathChart = new InferenceChart(ifactory.getResourceString(PATH_TITLE), ifactory.getResourceString(PATH_X_AXIS), ifactory.getResourceString(Y_AXIS), InferenceChart.LINE_CHART);
        cdfChart = new InferenceChart(ifactory.getResourceString(CDF_TITLE), ifactory.getResourceString(CDF_X_AXIS), ifactory.getResourceString(DISTRIBUTION_Y_AXIS), InferenceChart.LINE_CHART);
        tailChart = new InferenceChart(ifactory.getResourceString(TAIL_TITLE), ifactory.getResourceString(TAIL_X_AXIS), ifactory.getResourceString(DISTRIBUTION_Y_AXIS), InferenceChart.LINE_CHART);
        parameterPanel = new JPanel(new GridBagLayout());
        c = new GridBagConstraints();
        c.anchor = GridBagConstraints.WEST;
        c.gridx = 0;
        c.gridy = 0;
        parameterPanel.add(momentsPanel, c);
        c.gridy = 1;
        parameterPanel.add(hPanel, c);
        c.gridy = 2;
        parameterPanel.add(qPanel, c);

        this.getContentPane().add("North", menubar);
        this.getContentPane().add("Center", abas);
        this.getContentPane().add("South", parameterPanel);
    }

    /*********************************************************************/
    /*********************         ACTIONS           *********************/
    /*********************************************************************/
//    public static class OpenInferenceAction extends AbstractAction {
//
//        OpenInferenceAction() {
//            super("openInferenceAction");
//        }
//
//        public void actionPerformed(ActionEvent e) {
//            //TODO review open file action (too clumbersome)
//            JFileChooser fc = new JFileChooser(Path.getLogDir());
//            fc.setFileFilter(LogFile.Type.TIMESTAMP.getFileFilter());
//            fc.setDialogTitle("Open Inference File");
//
//            int o = fc.showOpenDialog(null);
//            switch (o) {
//                case JFileChooser.APPROVE_OPTION: {
//                    File inferencefile = (File) fc.getSelectedFile();
//                    if (inferencefile != null) {
//                        InferenceDataImporter dataimporter = new InferenceDataImporter(inferencefile);
//                        dataimporter.setSize(InferenceDataImporter.firstPaneDimension);
//                        dataimporter.setResizable(false);
//                        dataimporter.setVisible(true);
//                        GraphicInterface.getInstance().showInferencePanel();
//                    } else {
//                        Console.printError(Resource.getString("SELECT_VALID_FILE"));
//                    }
//                }
//                break;
//                case JFileChooser.CANCEL_OPTION: {
//                    Console.printError(Resource.getString("FILE_SELECTION_CANCELED"));
//                }
//                break;
//
//            }
//        }
//    }
    class DistributionAction extends AbstractAction {

        DistributionAction() {
            super(DISTRIBUTION_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            if (hasDistribution) {
                distChart.restart();
                abas.remove(distChart);
                hasDistribution = false;
            } else {
                inference.loadDistributionChart(distChart, seriesName);
                if (inference.getProcess().equals(Inference.PACKETS_PER_UNIT)) {
                    distChart.addLabel(new JLabel(ifactory.getResourceString(InferenceFrame.TIME_UNIT) + " = " + inference.getTimeUnit()));
                }
                abas.addTab(ifactory.getResourceString(InferenceFrame.DISTRIBUTION_TAB_TITLE), distChart);
                hasDistribution = true;
            }
        }
    }

    class CDFAction extends AbstractAction {

        CDFAction() {
            super(CDF_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            if (hasCdf) {
                cdfChart.restart();
                abas.remove(cdfChart);
                hasCdf = false;
            } else {
                inference.loadCDFChart(cdfChart, seriesName);
                if (inference.getProcess().equals(Inference.PACKETS_PER_UNIT)) {
                    cdfChart.addLabel(new JLabel(ifactory.getResourceString(InferenceFrame.TIME_UNIT) + " = " + inference.getTimeUnit()));
                }
                abas.addTab(ifactory.getResourceString(InferenceFrame.CDF_TAB_TITLE), cdfChart);
                hasCdf = true;
            }
        }
    }

    class TailAction extends AbstractAction {

        TailAction() {
            super(TAIL_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            if (hasTail) {
                tailChart.restart();
                abas.remove(tailChart);
                hasTail = false;
            } else {
                inference.loadTailDistributionChart(tailChart, seriesName);
                if (inference.getProcess().equals(Inference.PACKETS_PER_UNIT)) {
                    tailChart.addLabel(new JLabel(ifactory.getResourceString(InferenceFrame.TIME_UNIT) + " = " + inference.getTimeUnit()));
                }
                abas.addTab(ifactory.getResourceString(InferenceFrame.TAIL_TAB_TITLE), tailChart);
                hasTail = true;
            }
        }
    }

    class PathAction extends AbstractAction {

        PathAction() {
            super(SAMPLE_PATH_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            if (hasPath) {
                pathChart.restart();
                abas.remove(pathChart);
                hasPath = false;
            } else {
                inference.loadSamplePathChart(pathChart, seriesName);
                if (inference.getProcess().equals(Inference.PACKETS_PER_UNIT)) {
                    pathChart.addLabel(new JLabel(ifactory.getResourceString(InferenceFrame.TIME_UNIT) + " = " + inference.getTimeUnit()));
                }
                abas.addTab(ifactory.getResourceString(InferenceFrame.PATH_TAB_TITLE), pathChart);
                hasPath = true;
            }
        }
    }

    class VarianceTimePlotAction extends AbstractAction {

        VarianceTimePlotAction() {
            super(VTP_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            if (hasVTP) {
                vtpChart.restart();
                abas.remove(vtpChart);
                hasVTP = false;
            } else {
                inference.loadVTPChart(vtpChart, seriesName);
                if (inference.getProcess().equals(Inference.PACKETS_PER_UNIT)) {
                    pathChart.addLabel(new JLabel(ifactory.getResourceString(InferenceFrame.TIME_UNIT) + " = " + inference.getTimeUnit()));
                }
                abas.addTab(ifactory.getResourceString(InferenceFrame.VTP_TITLE), vtpChart);
                hasVTP = true;
            }
        }
    }

    void reselect() {
        /*try {
            setSelected(false);
            setSelected(true);
        } catch (PropertyVetoException pve) {
        }*/
    }

    private void restartFrame(String newTitle) {
        setTitle(newTitle);
        c.gridx = 0;
        c.gridy = 0;
        momentsPanel.removeAll();
        hPanel.removeAll();
        qPanel.removeAll();
        reselect();
        distChart.restart();
        abas.remove(distChart);
        hasDistribution = false;
        pathChart.restart();
        abas.remove(pathChart);
        hasPath = false;
        vtpChart.restart();
        abas.remove(vtpChart);
        hasVTP = false;
        logVtpChart.restart();
        abas.remove(logVtpChart);
        hasLogVTP = false;
    }

    class RemoveTrendAction extends AbstractAction {

        RemoveTrendAction() {
            super(REMOVE_TREND_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            inference.removeTrend(10);
            restartFrame(getTitle() + Resource.getString("TREND_REMOVED"));
        }
    }

    class LogVarianceTimePlotAction extends AbstractAction {

        LogVarianceTimePlotAction() {
            super(LOG_VTP_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            if (hasLogVTP) {
                logVtpChart.restart();
                abas.remove(logVtpChart);
                hasLogVTP = false;
            } else {
                inference.loadLogVTPChart(logVtpChart, seriesName);
                if (inference.getProcess().equals(Inference.PACKETS_PER_UNIT)) {
                    pathChart.addLabel(new JLabel(ifactory.getResourceString(InferenceFrame.TIME_UNIT) + " = " + inference.getTimeUnit()));
                }
                abas.addTab(ifactory.getResourceString(InferenceFrame.LOG_VTP_TITLE), logVtpChart);
                hasLogVTP = true;
            }
        }
    }

    class MeanAction extends AbstractAction {

        MeanAction() {
            super(MEAN_ACTION);
        }

        public void actionPerformed(ActionEvent e) {

            DecimalFormat twoPlaces = new DecimalFormat("0.000");
            c.gridx = 0;
            c.gridy = 0;
            momentsPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.MEAN_LABEL) + " = " + twoPlaces.format(inference.getMean()) + "     "), c);
            reselect();
        }
    }

    class VarianceAction extends AbstractAction {

        VarianceAction() {
            super(VARIANCE_ACTION);
        }

        public void actionPerformed(ActionEvent e) {

            DecimalFormat twoPlaces = new DecimalFormat("0.000");
            c.gridx = 1;
            c.gridy = 0;
            momentsPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.VARIANCE_LABEL) + " = " + twoPlaces.format(inference.getVariance())), c);
            reselect();
        }
    }

    private void createHurstFrame() {

        ButtonGroup bGH;
        JPanel hurstPanel;
        GridBagConstraints c;
        JLabel estimatorLabel, nameLabel;
        JButton calculateHurstButton;

        this.hurstFrame = new JFrame(ifactory.getResourceString(HURST_FRAME));
        whittleButton = ifactory.createRadioButton(WHITTLE_BUTTON, true);
        varianceTimeButton = ifactory.createRadioButton(VTP_BUTTON, false);
        kettaniButton = ifactory.createRadioButton(KETTANI_BUTTON, false);
        periodogramButton = ifactory.createRadioButton(PERIODOGRAM_BUTTON, false);
        allButton = ifactory.createRadioButton(ALL_BUTTON, false);
        estimatorLabel = ifactory.createLabel(ESTIMATOR);
        nameLabel = new JLabel(this.getTitle());
        bGH = new ButtonGroup();
        hurstPanel = new JPanel(new GridBagLayout());
        c = new GridBagConstraints();
        c.anchor = GridBagConstraints.WEST;
        calculateHurstButton = ifactory.createButton(CALCULATE_HURST);
        bGH.add(whittleButton);
        bGH.add(varianceTimeButton);
        bGH.add(kettaniButton);
        bGH.add(periodogramButton);
        bGH.add(allButton);

        c.gridx = 0;
        c.gridy = 0;
        hurstPanel.add(nameLabel, c);
        c.gridy = 1;
        hurstPanel.add(estimatorLabel, c);
        c.gridy = 2;
        hurstPanel.add(whittleButton, c);
        c.gridy = 3;
        hurstPanel.add(varianceTimeButton, c);
        c.gridy = 4;
        hurstPanel.add(kettaniButton, c);
        c.gridy = 5;
        hurstPanel.add(periodogramButton, c);
        c.gridy = 6;
        hurstPanel.add(allButton, c);
        c.gridy = 7;
        hurstPanel.add(calculateHurstButton, c);
        hurstFrame.getContentPane().add(hurstPanel);
        hurstFrame.setSize(200, 200);
        hurstFrame.setLocation(400, 200);
        hurstFrame.setResizable(true);
        //hurstFrame.setVisible(false);
        //	hurstFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

        //hurstFrame.setLocation(400, 200);
        hurstFrame.setVisible(true);
    }

    class CalculateHurstAction extends AbstractAction {

        CalculateHurstAction() {
            super(CALCULATE_HURST_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            double H;
            DecimalFormat twoPlaces = new DecimalFormat("0.000");
            c.gridy = 0;
            if (whittleButton.isSelected()) {
                H = inference.getHurst(Inference.WHITTLE_ESTIMATOR);
                c.gridx = 0;
                hPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.WHITTLE) + " = " + twoPlaces.format(H) + "     "), c);
            } else if (varianceTimeButton.isSelected()) {
                H = inference.getHurst(Inference.VARIANCE_TIME_PLOT_ESTIMATOR);
                c.gridx = 1;
                hPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.VTP) + " = " + twoPlaces.format(H) + "     "), c);
            } else if (kettaniButton.isSelected()) {
                H = inference.getHurst(Inference.KETTANI_GUBNER_ESTIMATOR);
                c.gridx = 2;
                hPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.KETTANI) + " = " + twoPlaces.format(H) + "     "), c);
            } else if (periodogramButton.isSelected()) {
                H = inference.getHurst(Inference.PERIODOGRAM_ESTIMATOR);
                c.gridx = 3;
                hPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.PERIODOGRAM) + " = " + twoPlaces.format(H) + "     "), c);
            } else if (allButton.isSelected()) {
                H = inference.getHurst(Inference.WHITTLE_ESTIMATOR);
                c.gridx = 0;
                hPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.WHITTLE) + " = " + twoPlaces.format(H) + "     "), c);
                H = inference.getHurst(Inference.VARIANCE_TIME_PLOT_ESTIMATOR);
                c.gridx = 1;
                hPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.VTP) + " = " + twoPlaces.format(H) + "     "), c);
                H = inference.getHurst(Inference.KETTANI_GUBNER_ESTIMATOR);
                c.gridx = 2;
                hPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.KETTANI) + " = " + twoPlaces.format(H) + "     "), c);
                H = inference.getHurst(Inference.PERIODOGRAM_ESTIMATOR);
                c.gridx = 3;
                hPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.PERIODOGRAM) + " = " + twoPlaces.format(H) + "     "), c);
            }
            reselect();
            hurstFrame.dispose();
        }
    }

    class HurstAction extends AbstractAction {

        HurstAction() {
            super(HURST_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            createHurstFrame();
        }
    }

    private void createQuiFrame() {

        JPanel quiPanel;
        GridBagConstraints c;
        JLabel distributionLabel, fileNameLabel;
        JButton calculateQuiButton;

        this.quiFrame = new JFrame(ifactory.getResourceString(QUI_FRAME));
        quiCombo = new XmlComboBox(CHI_SQUARE_XML);
        distributionLabel = ifactory.createLabel(QUI_DISTRIBUTION);
        fileNameLabel = new JLabel(this.getTitle());
        quiPanel = new JPanel(new GridBagLayout());
        c = new GridBagConstraints();
        c.anchor = GridBagConstraints.WEST;
        calculateQuiButton = ifactory.createButton(CALCULATE_QUI);

        c.gridx = 0;
        c.gridy = 0;
        quiPanel.add(fileNameLabel, c);
        c.gridy = 1;
        quiPanel.add(distributionLabel, c);
        c.gridy = 2;
        quiPanel.add(quiCombo, c);
        c.gridy = 3;
        quiPanel.add(calculateQuiButton, c);
        quiFrame.getContentPane().add(quiPanel);
        quiFrame.setSize(300, 200);
        quiFrame.setLocation(400, 200);
        quiFrame.setResizable(true);
        quiFrame.setVisible(false);
        //	quiFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

        quiFrame.setLocation(400, 200);
        quiFrame.setVisible(true);

    }

    private InferenceFrame getThisFrame() {
        return this;
    }

    class CalculateQuiAction extends AbstractAction {

        CalculateQuiAction() {
            super(CALCULATE_QUI_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            double qui = 0;
            DecimalFormat twoPlaces = new DecimalFormat("0.000");
            String distName = (String) quiCombo.getSelectedItem();
            GenericContinuousDistribution distribution = (GenericContinuousDistribution) XmlFactory.getNewInstanceFromXML(CHI_SQUARE_XML, distName);
            try {
                distribution.estimateParameters(inference);
                qui = inference.getQui(distribution);
                if (currentQuiGridx > 2) {
                    qPanel.remove(0);
                }
                qPanel.add(new JLabel(ifactory.getResourceString(InferenceFrame.QUI) + "(" + distName + "-" + ifactory.getResourceString(InferenceFrame.DEGREES) + ": " + inference.getDegreesOfFreedom() + ")" + " = " + twoPlaces.format(qui) + "  "));
                reselect();
                currentQuiGridx++;
            } catch (IllegalArgumentException iae) {
                Console.showMessageDialog(iae.getMessage());
            }
            quiFrame.dispose();
        }
    }

    class QuiSquareAction extends AbstractAction {

        QuiSquareAction() {
            super(QUI_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            createQuiFrame();
        }
    }

    class DegreesOfFreedomAction extends AbstractAction {

        DegreesOfFreedomAction() {
            super(DEGREES_OF_FREEDOM_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            String degreesString = JOptionPane.showInputDialog(ifactory.getResourceString(InferenceFrame.DEGREES_COMAND));
            try {
                int degrees = Integer.parseInt(degreesString);
                if (degrees > 0) {
                    inference.setDegreesOfFreedom(degrees);
                } else {
                    throw new NumberFormatException("");
                }
            } catch (NumberFormatException nfe) {
                Console.showMessageDialog(ifactory.getResourceString(InferenceFrame.DEGREES_ERROR));
            }
        }
    }
}
